package com.photoeditor.demo.util.gl;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;

import com.android.gl.renderer.ISurfaceRenderer;
import com.android.gl.view.ISurface;
import com.android.gl.view.SurfaceView;
import com.android.gpuimage.AdjustGPUImageView;
import com.android.gpuimage.GPUImageFilterGroup;
import com.android.gpuimage.GPUImageLookupFilter;
import com.android.gpuimage.GPUImageSoftLightBlendFilter;
import com.android.gpuimage.GPUImageTwoInputFilter;
import com.common.base.utils.thread.ThreadPool;
import com.photoeditor.R;
import com.photoeditor.demo.util.gl.model.DynamicPoint;
import com.photoeditor.demo.util.gl.model.Ornament;
import com.photoeditor.demo.util.gl.util.OrnamentFactory;
import com.photoeditor.demo.model.bean.face.CommonFaceBean;
import com.photoeditor.demo.ui.widget.oldify.OldifyDecoration;
import com.photoeditor.demo.ui.widget.oldify.OldifyDecorationContainer;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by @author winn on 2018/11/29.
 * 合成老化效果图
 * 实现思路：
 * 1. 人脸检测，生成关键点（本类不包含人脸检测，外部实现，并传入关键点）
 * 2. 根据关键点，修改老化皱纹模型中顶点坐标，生成与用户相匹配的老化皱纹效果图（暂时使用rajavali渲染，
 *    生成的效果图大小跟传入的用户图片大小一致）
 * 3. 根据用户图片 + 老化皱纹效果图 使用opengl混合生成最终效果图
 */

public class OldifyEffectFactory implements My3DRenderer.OrnamentChangeListener, SurfaceView.OnTakeScreenshotListener {

    private static final String TAG = OldifyEffectFactory.class.getSimpleName();
    public static final int OLDIFY_TYPE_NONE = 0;
    public static final int OLDIFY_TYPE_50 = 50;
    public static final int OLDIFY_TYPE_70 = 70;
    public static final int OLDIFY_TYPE_90 = 90;
    public static final String OLDIFY_50_TEXTURE = "ic_oldify_effect_50.png";
    public static final String OLDIFY_70_TEXTURE = "ic_oldify_effect_70.png";
    public static final String OLDIFY_90_TEXTURE = "ic_oldify_effect_90.png";

    private Context mContext;
    /** 用户图片 **/
    private Bitmap mSrcImageOnScreen;
    /** 根据用户图片识别出的关键点 **/
    private List<DynamicPoint> mPointList;
    private CommonFaceBean mFaceBean;
    private Ornament mCurrentOrnament;

    private ISurface mRenderSurface;
    private ISurfaceRenderer mISurfaceRenderer;
    // 用于效果融合
    private AdjustGPUImageView mAdjustGPUImageView;
    private WeakReference<OnBuildOldifyImgListener> mBuildImgListener;
    private int mCurOldifyType;
    private OldifyDecorationContainer mDecorationView;
    private boolean mIsAddOldifyEffect;
    private PointF mPosBelowLeftEye, mPosRightForeHead;

    public OldifyEffectFactory(Context context, Bitmap src, CommonFaceBean faceBean, boolean isAddOldifyEffect) {
        mContext = context;
        mSrcImageOnScreen = src;
        mFaceBean = faceBean;
        mIsAddOldifyEffect = isAddOldifyEffect;
        generateDecPos();
    }

    private void generateDecPos() {
        float x = mFaceBean.leftEye.get(0).x;
        float y = (mFaceBean.noseBridge.get(1).y - mFaceBean.noseBridge.get(0).y) / 3f + mFaceBean.leftEye.get(0).y;
        mPosBelowLeftEye = new PointF(x, y);

        x = mFaceBean.faceOval.get(2).x;
        y = mFaceBean.faceOval.get(2).y + (mFaceBean.rightEyeBrowTop.get(3).y - mFaceBean.faceOval.get(2).y) / 4f;
        mPosRightForeHead = new PointF(x, y);
    }

    public void bindView(SurfaceView surfaceView, My3DRenderer render, AdjustGPUImageView gpuImage, OldifyDecorationContainer decorationView) {
        mRenderSurface = surfaceView;
        mISurfaceRenderer = render;
        mAdjustGPUImageView = gpuImage;
        mDecorationView = decorationView;
        ((My3DRenderer) mISurfaceRenderer).setOrnamentChangeListener(this);
        ((SurfaceView)mRenderSurface).setOnTakeScreenshotListener(this);
    }

    public boolean oldify(int type) {
        mCurOldifyType = type;
        mCurrentOrnament = OrnamentFactory.getOldifyEffectMask(type);
        if (mCurrentOrnament == null) return false;
        if (mFaceBean == null) return false;
        if (mPointList == null || mPointList.size() == 0) mPointList = getNewFaceObjDynamicPoints(mFaceBean);
        if (mDecorationView != null && mIsAddOldifyEffect) addOldifyDec(type);
        ((My3DRenderer)mISurfaceRenderer).setDynamicPoints(mPointList);
        ((My3DRenderer)mISurfaceRenderer).setTextureName(getTextureName(type));
        ((My3DRenderer)mISurfaceRenderer).setOrnamentModel(mCurrentOrnament);
        ((My3DRenderer)mISurfaceRenderer).setIsNeedUpdateOrnament(true);
        ((My3DRenderer)mISurfaceRenderer).changeOrnament(true);
        return true;
    }

    private void addOldifyDec(int type) {
        OldifyDecoration dec = null;
        mDecorationView.clear();
        switch (type) {
            case OLDIFY_TYPE_50:
                break;
            case OLDIFY_TYPE_70:
                dec = new OldifyDecoration(mContext, R.drawable.ic_emoji_heart);
                mDecorationView.addOldifyDecoration(dec, mPosBelowLeftEye.x, mPosBelowLeftEye.y);
                break;
            case OLDIFY_TYPE_90:
                dec = new OldifyDecoration(mContext, R.drawable.ic_emoji_heart);
                mDecorationView.addOldifyDecoration(dec, mPosRightForeHead.x, mPosRightForeHead.y);
                break;
        }
    }

    private String getTextureName(int type) {
        switch (type) {
            case OLDIFY_TYPE_70:
                return OLDIFY_70_TEXTURE;
            case OLDIFY_TYPE_90:
                return OLDIFY_90_TEXTURE;
            case OLDIFY_TYPE_50:
            default:
                return OLDIFY_50_TEXTURE;
        }
    }

    public void destroy() {
        if (isRendering()) {
            stopRender();
        }
        if (mBuildImgListener != null && mBuildImgListener.get() != null) {
            mBuildImgListener.clear();
            mBuildImgListener = null;
        }
    }

    @Override
    public void onOrnamentChange() {
        ((SurfaceView)mRenderSurface).takeScreenshot();
    }

    @Override
    public void onTakeScreenshot(final Bitmap bitmap) {
        stopRender();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Bitmap decoration = mDecorationView.getDecoration();
                Bitmap result = mergeImg(bitmap, decoration, mSrcImageOnScreen, true);
                notifyListener(result, mCurOldifyType);
            }
        }).start();
    }

    public void setOnBuildOdifyImgListener(OnBuildOldifyImgListener listener) {
        if (listener != null) {
            mBuildImgListener = new WeakReference<OnBuildOldifyImgListener>(listener);
        } else {
            if (mBuildImgListener != null) {
                if (mBuildImgListener.get() != null) mBuildImgListener.clear();
                mBuildImgListener = null;
            }
        }

    }

    private Bitmap mergeImg(Bitmap oldifyEffect, Bitmap decoration, Bitmap srcImage, boolean canRetry) {
        if (oldifyEffect == null || oldifyEffect.isRecycled() || srcImage == null || srcImage.isRecycled()) {
            return null;
        }
        Bitmap oldifyEffectWithDec = null;
        if (decoration != null && !decoration.isRecycled()) {
            oldifyEffectWithDec = addOldifyDecoration2Src(decoration, oldifyEffect);
        }

        GPUImageFilterGroup filterGroup = getFilter4Merge(oldifyEffectWithDec == null ? oldifyEffect : oldifyEffectWithDec);
        Bitmap bitmap = mAdjustGPUImageView.getCurrentBitmap(srcImage, filterGroup);
        // 如果失败，尝试重新生成，只重新尝试一次
        if (bitmap == null && canRetry) {
            bitmap = mAdjustGPUImageView.getCurrentBitmap(srcImage, filterGroup);
        }

        return bitmap;
    }

    /**
     * decoration和src的size相当，且decoration的位置已经调整好了
     * @param decoration
     * @param src
     * @return
     */
    private Bitmap addOldifyDecoration2Src(Bitmap decoration, Bitmap src) {
        Bitmap res = src.copy(Bitmap.Config.ARGB_4444, true);
        Canvas canvas = new Canvas(res);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        canvas.drawBitmap(decoration, 0, 0, paint);
        return res;
    }

    private GPUImageFilterGroup getFilter4Merge(Bitmap effect) {
        GPUImageFilterGroup res = new GPUImageFilterGroup();
        GPUImageLookupFilter lookupFilterPre = new GPUImageLookupFilter();
        GPUImageTwoInputFilter filter = new GPUImageSoftLightBlendFilter();
        GPUImageLookupFilter lookupFilterPost = new GPUImageLookupFilter();
        filter.setBitmap(effect);
        switch (mCurOldifyType) {
            case OLDIFY_TYPE_50:
                lookupFilterPost.setBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_merge_filter_post_50));
                res.addFilter(filter);
                res.addFilter(lookupFilterPost);
                break;
            case OLDIFY_TYPE_70:
                lookupFilterPre.setBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_fliter_pre));
                lookupFilterPost.setBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_merge_filter_post_70));

                res.addFilter(lookupFilterPre);
                res.addFilter(filter);
                res.addFilter(lookupFilterPost);
                break;
            case OLDIFY_TYPE_90:
                lookupFilterPre.setBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_fliter_pre));
                lookupFilterPost.setBitmap(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_merge_filter_post_90));

                res.addFilter(lookupFilterPre);
                res.addFilter(filter);
                res.addFilter(lookupFilterPost);
                break;
        }
        return res;
    }


    public boolean stopRender() {
        return ((My3DRenderer)mISurfaceRenderer).stopRendering();
    }

    public boolean isRendering() {
        return ((My3DRenderer)mISurfaceRenderer).isRendering();
    }

    public void startRender() {
        ((My3DRenderer)mISurfaceRenderer).startRendering();
    }

    private void notifyListener(final Bitmap dstImage,final int oldifyType) {
        if (mBuildImgListener != null && mBuildImgListener.get() != null) {
            final OnBuildOldifyImgListener listener = mBuildImgListener.get();
            ThreadPool.runUITask(new Runnable() {
                @Override
                public void run() {
                    listener.onBuildOldifyImg(dstImage, oldifyType);
                }
            });
        }
    }

    /**
     * DynnamicPoint中没有faceOval的0号点；
     * DynamicPoint中索引为62的点为废点，无需使用
     */
    private List<DynamicPoint> getGvDynamicPoints(CommonFaceBean bean) {
        List<DynamicPoint> list = new ArrayList<>();

        bean.scaleScreenCoord(1f / mSrcImageOnScreen.getWidth(), 1f / mSrcImageOnScreen.getHeight());
        bean.transScreenCoord2GlCoord();

        //废点，无需使用
        list.add(new DynamicPoint(62, 0, 0, 0));

        //上嘴唇上端
        list.add(new DynamicPoint(52, bean.upperLipTop.get(0).x, bean.upperLipTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(7, bean.upperLipTop.get(1).x, bean.upperLipTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(8, bean.upperLipTop.get(2).x, bean.upperLipTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(0, bean.upperLipTop.get(3).x, bean.upperLipTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(1, bean.upperLipTop.get(4).x, bean.upperLipTop.get(4).y, 0.0f));
        list.add(new DynamicPoint(49, bean.upperLipTop.get(5).x, bean.upperLipTop.get(5).y, 0.0f));
        list.add(new DynamicPoint(74, bean.upperLipTop.get(6).x, bean.upperLipTop.get(6).y, 0.0f));
        list.add(new DynamicPoint(73, bean.upperLipTop.get(7).x, bean.upperLipTop.get(7).y, 0.0f));
        list.add(new DynamicPoint(80, bean.upperLipTop.get(8).x, bean.upperLipTop.get(8).y, 0.0f));
        list.add(new DynamicPoint(79, bean.upperLipTop.get(9).x, bean.upperLipTop.get(9).y, 0.0f));
        list.add(new DynamicPoint(118, bean.upperLipTop.get(10).x, bean.upperLipTop.get(10).y, 0.0f));

        //上嘴唇下端
        list.add(new DynamicPoint(2, bean.upperLipBottom.get(0).x, bean.upperLipBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(5, bean.upperLipBottom.get(1).x, bean.upperLipBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(64, bean.upperLipBottom.get(2).x, bean.upperLipBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(35, bean.upperLipBottom.get(3).x, bean.upperLipBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(46, bean.upperLipBottom.get(4).x, bean.upperLipBottom.get(4).y, 0.0f));
        list.add(new DynamicPoint(104, bean.upperLipBottom.get(5).x, bean.upperLipBottom.get(5).y, 0.0f));
        list.add(new DynamicPoint(128, bean.upperLipBottom.get(6).x, bean.upperLipBottom.get(6).y, 0.0f));
        list.add(new DynamicPoint(77, bean.upperLipBottom.get(7).x, bean.upperLipBottom.get(7).y, 0.0f));
        list.add(new DynamicPoint(75, bean.upperLipBottom.get(8).x, bean.upperLipBottom.get(8).y, 0.0f));

        //下嘴唇上端
        list.add(new DynamicPoint(124, bean.lowLipTop.get(0).x, bean.lowLipTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(113, bean.lowLipTop.get(1).x, bean.lowLipTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(88, bean.lowLipTop.get(2).x, bean.lowLipTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(93, bean.lowLipTop.get(3).x, bean.lowLipTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(57, bean.lowLipTop.get(4).x, bean.lowLipTop.get(4).y, 0.0f));
        list.add(new DynamicPoint(23, bean.lowLipTop.get(5).x, bean.lowLipTop.get(5).y, 0.0f));
        list.add(new DynamicPoint(17, bean.lowLipTop.get(6).x, bean.lowLipTop.get(6).y, 0.0f));
        list.add(new DynamicPoint(45, bean.lowLipTop.get(7).x, bean.lowLipTop.get(7).y, 0.0f));
        list.add(new DynamicPoint(59, bean.lowLipTop.get(8).x, bean.lowLipTop.get(8).y, 0.0f));

        //下嘴唇下端
        list.add(new DynamicPoint(132, bean.lowLipBottom.get(0).x, bean.lowLipBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(134, bean.lowLipBottom.get(1).x, bean.lowLipBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(111, bean.lowLipBottom.get(2).x, bean.lowLipBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(98, bean.lowLipBottom.get(3).x, bean.lowLipBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(3, bean.lowLipBottom.get(4).x, bean.lowLipBottom.get(4).y, 0.0f));
        list.add(new DynamicPoint(28, bean.lowLipBottom.get(5).x, bean.lowLipBottom.get(5).y, 0.0f));
        list.add(new DynamicPoint(42, bean.lowLipBottom.get(6).x, bean.lowLipBottom.get(6).y, 0.0f));
        list.add(new DynamicPoint(71, bean.lowLipBottom.get(7).x, bean.lowLipBottom.get(7).y, 0.0f));
        list.add(new DynamicPoint(69, bean.lowLipBottom.get(8).x, bean.lowLipBottom.get(8).y, 0.0f));

        //脸轮廓
        //没有faceOval的0号点
        list.add(new DynamicPoint(89, bean.faceOval.get(1).x, bean.faceOval.get(1).y, 0.0f));
        list.add(new DynamicPoint(129, bean.faceOval.get(2).x, bean.faceOval.get(2).y, 0.0f));
        list.add(new DynamicPoint(121, bean.faceOval.get(3).x, bean.faceOval.get(3).y, 0.0f));
        list.add(new DynamicPoint(85, bean.faceOval.get(4).x, bean.faceOval.get(4).y, 0.0f));
        list.add(new DynamicPoint(99, bean.faceOval.get(5).x, bean.faceOval.get(5).y, 0.0f));
        list.add(new DynamicPoint(133, bean.faceOval.get(6).x, bean.faceOval.get(6).y, 0.0f));
        list.add(new DynamicPoint(116, bean.faceOval.get(7).x, bean.faceOval.get(7).y, 0.0f));
        list.add(new DynamicPoint(130, bean.faceOval.get(8).x, bean.faceOval.get(8).y, 0.0f));
        list.add(new DynamicPoint(123, bean.faceOval.get(9).x, bean.faceOval.get(9).y, 0.0f));
        list.add(new DynamicPoint(107, bean.faceOval.get(10).x, bean.faceOval.get(10).y, 0.0f));
        list.add(new DynamicPoint(100, bean.faceOval.get(11).x, bean.faceOval.get(11).y, 0.0f));
        list.add(new DynamicPoint(106, bean.faceOval.get(12).x, bean.faceOval.get(12).y, 0.0f));
        list.add(new DynamicPoint(90, bean.faceOval.get(13).x, bean.faceOval.get(13).y, 0.0f));
        list.add(new DynamicPoint(108, bean.faceOval.get(14).x, bean.faceOval.get(14).y, 0.0f));
        list.add(new DynamicPoint(103, bean.faceOval.get(15).x, bean.faceOval.get(15).y, 0.0f));
        list.add(new DynamicPoint(76, bean.faceOval.get(16).x, bean.faceOval.get(16).y, 0.0f));
        list.add(new DynamicPoint(105, bean.faceOval.get(17).x, bean.faceOval.get(17).y, 0.0f));
        list.add(new DynamicPoint(10, bean.faceOval.get(18).x, bean.faceOval.get(18).y, 0.0f));
        list.add(new DynamicPoint(36, bean.faceOval.get(19).x, bean.faceOval.get(19).y, 0.0f));
        list.add(new DynamicPoint(4, bean.faceOval.get(20).x, bean.faceOval.get(20).y, 0.0f));
        list.add(new DynamicPoint(34, bean.faceOval.get(21).x, bean.faceOval.get(21).y, 0.0f));
        list.add(new DynamicPoint(39, bean.faceOval.get(22).x, bean.faceOval.get(22).y, 0.0f));
        list.add(new DynamicPoint(20, bean.faceOval.get(23).x, bean.faceOval.get(23).y, 0.0f));
        list.add(new DynamicPoint(37, bean.faceOval.get(24).x, bean.faceOval.get(24).y, 0.0f));
        list.add(new DynamicPoint(31, bean.faceOval.get(25).x, bean.faceOval.get(25).y, 0.0f));
        list.add(new DynamicPoint(38, bean.faceOval.get(26).x, bean.faceOval.get(26).y, 0.0f));
        list.add(new DynamicPoint(58, bean.faceOval.get(27).x, bean.faceOval.get(27).y, 0.0f));
        list.add(new DynamicPoint(67, bean.faceOval.get(28).x, bean.faceOval.get(28).y, 0.0f));
        list.add(new DynamicPoint(50, bean.faceOval.get(29).x, bean.faceOval.get(29).y, 0.0f));
        list.add(new DynamicPoint(70, bean.faceOval.get(30).x, bean.faceOval.get(30).y, 0.0f));
        list.add(new DynamicPoint(30, bean.faceOval.get(31).x, bean.faceOval.get(31).y, 0.0f));
        list.add(new DynamicPoint(14, bean.faceOval.get(32).x, bean.faceOval.get(32).y, 0.0f));
        list.add(new DynamicPoint(55, bean.faceOval.get(33).x, bean.faceOval.get(33).y, 0.0f));
        list.add(new DynamicPoint(65, bean.faceOval.get(34).x, bean.faceOval.get(34).y, 0.0f));
        list.add(new DynamicPoint(18, bean.faceOval.get(35).x, bean.faceOval.get(35).y, 0.0f));

        //鼻梁
        list.add(new DynamicPoint(44, bean.noseBridge.get(0).x, bean.noseBridge.get(0).y, 0.0f));
        list.add(new DynamicPoint(19, bean.noseBridge.get(1).x, bean.noseBridge.get(1).y, 0.0f));

        //鼻子底部
        list.add(new DynamicPoint(33, bean.noseBottom.get(0).x, bean.noseBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(29, bean.noseBottom.get(1).x, bean.noseBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(102, bean.noseBottom.get(2).x, bean.noseBottom.get(2).y, 0.0f));

        //左眼
        list.add(new DynamicPoint(43, bean.leftEye.get(0).x, bean.leftEye.get(0).y, 0.0f));
        list.add(new DynamicPoint(15, bean.leftEye.get(1).x, bean.leftEye.get(1).y, 0.0f));
        list.add(new DynamicPoint(54, bean.leftEye.get(2).x, bean.leftEye.get(2).y, 0.0f));
        list.add(new DynamicPoint(41, bean.leftEye.get(3).x, bean.leftEye.get(3).y, 0.0f));
        list.add(new DynamicPoint(16, bean.leftEye.get(4).x, bean.leftEye.get(4).y, 0.0f));
        list.add(new DynamicPoint(22, bean.leftEye.get(5).x, bean.leftEye.get(5).y, 0.0f));
        list.add(new DynamicPoint(13, bean.leftEye.get(6).x, bean.leftEye.get(6).y, 0.0f));
        list.add(new DynamicPoint(47, bean.leftEye.get(7).x, bean.leftEye.get(7).y, 0.0f));
        list.add(new DynamicPoint(61, bean.leftEye.get(8).x, bean.leftEye.get(8).y, 0.0f));
        list.add(new DynamicPoint(68, bean.leftEye.get(9).x, bean.leftEye.get(9).y, 0.0f));
        list.add(new DynamicPoint(63, bean.leftEye.get(10).x, bean.leftEye.get(10).y, 0.0f));
        list.add(new DynamicPoint(6, bean.leftEye.get(11).x, bean.leftEye.get(11).y, 0.0f));
        list.add(new DynamicPoint(48, bean.leftEye.get(12).x, bean.leftEye.get(12).y, 0.0f));
        list.add(new DynamicPoint(56, bean.leftEye.get(13).x, bean.leftEye.get(13).y, 0.0f));
        list.add(new DynamicPoint(32, bean.leftEye.get(14).x, bean.leftEye.get(14).y, 0.0f));
        list.add(new DynamicPoint(51, bean.leftEye.get(15).x, bean.leftEye.get(15).y, 0.0f));

        //左眉上端
        list.add(new DynamicPoint(21, bean.leftEyeBrowTop.get(0).x, bean.leftEyeBrowTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(9, bean.leftEyeBrowTop.get(1).x, bean.leftEyeBrowTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(26, bean.leftEyeBrowTop.get(2).x, bean.leftEyeBrowTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(11, bean.leftEyeBrowTop.get(3).x, bean.leftEyeBrowTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(60, bean.leftEyeBrowTop.get(4).x, bean.leftEyeBrowTop.get(4).y, 0.0f));

        //左眉下端
        list.add(new DynamicPoint(40, bean.leftEyeBrowBottom.get(0).x, bean.leftEyeBrowBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(25, bean.leftEyeBrowBottom.get(1).x, bean.leftEyeBrowBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(27, bean.leftEyeBrowBottom.get(2).x, bean.leftEyeBrowBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(24, bean.leftEyeBrowBottom.get(3).x, bean.leftEyeBrowBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(53, bean.leftEyeBrowBottom.get(4).x, bean.leftEyeBrowBottom.get(4).y, 0.0f));

        //右眼
        list.add(new DynamicPoint(126, bean.rightEye.get(0).x, bean.rightEye.get(0).y, 0.0f));
        list.add(new DynamicPoint(114, bean.rightEye.get(1).x, bean.rightEye.get(1).y, 0.0f));
        list.add(new DynamicPoint(84, bean.rightEye.get(2).x, bean.rightEye.get(2).y, 0.0f));
        list.add(new DynamicPoint(92, bean.rightEye.get(3).x, bean.rightEye.get(3).y, 0.0f));
        list.add(new DynamicPoint(87, bean.rightEye.get(4).x, bean.rightEye.get(4).y, 0.0f));
        list.add(new DynamicPoint(110, bean.rightEye.get(5).x, bean.rightEye.get(5).y, 0.0f));
        list.add(new DynamicPoint(120, bean.rightEye.get(6).x, bean.rightEye.get(6).y, 0.0f));
        list.add(new DynamicPoint(86, bean.rightEye.get(7).x, bean.rightEye.get(7).y, 0.0f));
        list.add(new DynamicPoint(112, bean.rightEye.get(8).x, bean.rightEye.get(8).y, 0.0f));
        list.add(new DynamicPoint(117, bean.rightEye.get(9).x, bean.rightEye.get(9).y, 0.0f));
        list.add(new DynamicPoint(101, bean.rightEye.get(10).x, bean.rightEye.get(10).y, 0.0f));
        list.add(new DynamicPoint(122, bean.rightEye.get(11).x, bean.rightEye.get(11).y, 0.0f));
        list.add(new DynamicPoint(115, bean.rightEye.get(12).x, bean.rightEye.get(12).y, 0.0f));
        list.add(new DynamicPoint(78, bean.rightEye.get(13).x, bean.rightEye.get(13).y, 0.0f));
        list.add(new DynamicPoint(127, bean.rightEye.get(14).x, bean.rightEye.get(14).y, 0.0f));
        list.add(new DynamicPoint(131, bean.rightEye.get(15).x, bean.rightEye.get(15).y, 0.0f));

        //右眉上端
        list.add(new DynamicPoint(91, bean.rightEyeBrowTop.get(0).x, bean.rightEyeBrowTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(81, bean.rightEyeBrowTop.get(1).x, bean.rightEyeBrowTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(96, bean.rightEyeBrowTop.get(2).x, bean.rightEyeBrowTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(82, bean.rightEyeBrowTop.get(3).x, bean.rightEyeBrowTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(125, bean.rightEyeBrowTop.get(4).x, bean.rightEyeBrowTop.get(4).y, 0.0f));

        //右眉下端
        list.add(new DynamicPoint(109, bean.rightEyeBrowBottom.get(0).x, bean.rightEyeBrowBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(95, bean.rightEyeBrowBottom.get(1).x, bean.rightEyeBrowBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(97, bean.rightEyeBrowBottom.get(2).x, bean.rightEyeBrowBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(94, bean.rightEyeBrowBottom.get(3).x, bean.rightEyeBrowBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(119, bean.rightEyeBrowBottom.get(4).x, bean.rightEyeBrowBottom.get(4).y, 0.0f));

        //脖子中点（模拟）
        //x为下巴点的x，y为下巴位置 + 下巴到耳朵底部的垂直距离
        list.add(new DynamicPoint(72, bean.faceOval.get(18).x, bean.faceOval.get(18).y + bean.faceOval.get(18).y - bean.faceOval.get(11).y, 0.0f));

        //发际线3个顶点
        float dist2Top = ((bean.leftEyeBrowTop.get(3).y + bean.rightEyeBrowTop.get(3).y) / 2 -
                (bean.faceOval.get(0).y + bean.faceOval.get(35).y) / 2) * 0.6f;
        //poxX: 脸轮廓的起、止点的中点，模拟发际线的x位置；
        float posX = (bean.faceOval.get(0).x + bean.faceOval.get(35).x) / 2;
        float posY = (bean.faceOval.get(0).y + bean.faceOval.get(35).y) / 2 - dist2Top;
        //发际线中部点
        list.add(new DynamicPoint(66, posX, posY, 0.0f));

        //发际线左右端点
        posX = (bean.faceOval.get(31).x + bean.faceOval.get(32).x) / 2;
        posY = (bean.faceOval.get(31).y + bean.faceOval.get(32).y) / 2 - dist2Top;
        list.add(new DynamicPoint(12, posX, posY, 0.0f));

        posX = (bean.faceOval.get(4).x + bean.faceOval.get(5).x) / 2;
        posY = (bean.faceOval.get(4).y + bean.faceOval.get(5).y) / 2 - dist2Top;
        list.add(new DynamicPoint(83, posX, posY, 0.0f));

        return list;
    }

    private List<DynamicPoint> getNewFaceObjDynamicPoints(CommonFaceBean bean) {
        List<DynamicPoint> list = new ArrayList<>();

        bean.scaleScreenCoord(1f / mSrcImageOnScreen.getWidth(), 1f / mSrcImageOnScreen.getHeight());
        bean.transScreenCoord2GlCoord();

        //脸轮廓
        /**
         * 56、73、8、17、26、97、91、83、45这个9个点需要在原有的基础上手动下移；
         * 下移至贴近眉毛；
         */
        /*list.add(new DynamicPoint(56, bean.faceOval.get(0).x, bean.faceOval.get(0).y, 0.0f));
        list.add(new DynamicPoint(73, bean.faceOval.get(1).x, bean.faceOval.get(1).y, 0.0f));
        list.add(new DynamicPoint(8, bean.faceOval.get(2).x, bean.faceOval.get(2).y, 0.0f));
        list.add(new DynamicPoint(17, bean.faceOval.get(3).x, bean.faceOval.get(3).y, 0.0f));
        list.add(new DynamicPoint(26, bean.faceOval.get(4).x, bean.faceOval.get(4).y, 0.0f));
        list.add(new DynamicPoint(97, bean.faceOval.get(32).x, bean.faceOval.get(32).y, 0.0f));
        list.add(new DynamicPoint(91, bean.faceOval.get(33).x, bean.faceOval.get(33).y, 0.0f));
        list.add(new DynamicPoint(83, bean.faceOval.get(34).x, bean.faceOval.get(34).y, 0.0f));
        list.add(new DynamicPoint(45, bean.faceOval.get(35).x, bean.faceOval.get(35).y, 0.0f));*/

        float distRatioBetweenFaceAndEyeBrow = 0.4f;
        float diff = (bean.leftEyeBrowTop.get(4).y + bean.rightEyeBrowTop.get(4).y) / 2f - bean.faceOval.get(0).y;
        float realVal = (bean.leftEyeBrowTop.get(4).y + bean.rightEyeBrowTop.get(4).y) / 2f - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(56, bean.faceOval.get(0).x, realVal, 0.0f));

        diff = bean.rightEyeBrowTop.get(4).y - bean.faceOval.get(1).y;
        realVal = bean.rightEyeBrowTop.get(4).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(73, bean.faceOval.get(1).x, realVal, 0.0f));

        diff = bean.rightEyeBrowTop.get(3).y - bean.faceOval.get(2).y;
        realVal = bean.rightEyeBrowTop.get(3).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(8, bean.faceOval.get(2).x, realVal, 0.0f));

        diff = bean.rightEyeBrowTop.get(2).y - bean.faceOval.get(3).y;
        realVal = bean.rightEyeBrowTop.get(2).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(17, bean.faceOval.get(3).x, realVal, 0.0f));

        diff = bean.rightEyeBrowTop.get(1).y - bean.faceOval.get(4).y;
        realVal = bean.rightEyeBrowTop.get(1).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(26, bean.faceOval.get(4).x, realVal, 0.0f));

        diff = bean.leftEyeBrowTop.get(1).y - bean.faceOval.get(32).y;
        realVal = bean.leftEyeBrowTop.get(1).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(97, bean.faceOval.get(32).x, realVal, 0.0f));

        diff = bean.leftEyeBrowTop.get(2).y - bean.faceOval.get(33).y;
        realVal = bean.leftEyeBrowTop.get(2).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(91, bean.faceOval.get(33).x, realVal, 0.0f));

        diff = bean.leftEyeBrowTop.get(3).y - bean.faceOval.get(34).y;
        realVal = bean.leftEyeBrowTop.get(3).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(83, bean.faceOval.get(34).x, realVal, 0.0f));

        diff = bean.leftEyeBrowTop.get(4).y - bean.faceOval.get(35).y;
        realVal = bean.leftEyeBrowTop.get(4).y - diff * distRatioBetweenFaceAndEyeBrow;
        list.add(new DynamicPoint(45, bean.faceOval.get(35).x, realVal, 0.0f));

        //下述点不用手动调整
        list.add(new DynamicPoint(54, bean.faceOval.get(5).x, bean.faceOval.get(5).y, 0.0f));
        list.add(new DynamicPoint(52, bean.faceOval.get(6).x, bean.faceOval.get(6).y, 0.0f));
        list.add(new DynamicPoint(53, bean.faceOval.get(7).x, bean.faceOval.get(7).y, 0.0f));
        list.add(new DynamicPoint(35, bean.faceOval.get(8).x, bean.faceOval.get(8).y, 0.0f));
        list.add(new DynamicPoint(51, bean.faceOval.get(9).x, bean.faceOval.get(9).y, 0.0f));
        list.add(new DynamicPoint(31, bean.faceOval.get(10).x, bean.faceOval.get(10).y, 0.0f));
        list.add(new DynamicPoint(4, bean.faceOval.get(11).x, bean.faceOval.get(11).y, 0.0f));
        list.add(new DynamicPoint(0, bean.faceOval.get(12).x, bean.faceOval.get(12).y, 0.0f));
        list.add(new DynamicPoint(1, bean.faceOval.get(13).x, bean.faceOval.get(13).y, 0.0f));
        list.add(new DynamicPoint(3, bean.faceOval.get(14).x, bean.faceOval.get(14).y, 0.0f));
        list.add(new DynamicPoint(14, bean.faceOval.get(15).x, bean.faceOval.get(15).y, 0.0f));
        list.add(new DynamicPoint(36, bean.faceOval.get(16).x, bean.faceOval.get(16).y, 0.0f));
        list.add(new DynamicPoint(28, bean.faceOval.get(17).x, bean.faceOval.get(17).y, 0.0f));
        list.add(new DynamicPoint(49, bean.faceOval.get(18).x, bean.faceOval.get(18).y, 0.0f));
        list.add(new DynamicPoint(99, bean.faceOval.get(19).x, bean.faceOval.get(19).y, 0.0f));
        list.add(new DynamicPoint(107, bean.faceOval.get(20).x, bean.faceOval.get(20).y, 0.0f));
        list.add(new DynamicPoint(89, bean.faceOval.get(21).x, bean.faceOval.get(21).y, 0.0f));
        list.add(new DynamicPoint(78, bean.faceOval.get(22).x, bean.faceOval.get(22).y, 0.0f));
        list.add(new DynamicPoint(76, bean.faceOval.get(23).x, bean.faceOval.get(23).y, 0.0f));
        list.add(new DynamicPoint(75, bean.faceOval.get(24).x, bean.faceOval.get(24).y, 0.0f));
        list.add(new DynamicPoint(79, bean.faceOval.get(25).x, bean.faceOval.get(25).y, 0.0f));
        list.add(new DynamicPoint(102, bean.faceOval.get(26).x, bean.faceOval.get(26).y, 0.0f));
        list.add(new DynamicPoint(119, bean.faceOval.get(27).x, bean.faceOval.get(27).y, 0.0f));
        list.add(new DynamicPoint(106, bean.faceOval.get(28).x, bean.faceOval.get(28).y, 0.0f));
        list.add(new DynamicPoint(121, bean.faceOval.get(29).x, bean.faceOval.get(29).y, 0.0f));
        list.add(new DynamicPoint(120, bean.faceOval.get(30).x, bean.faceOval.get(30).y, 0.0f));
        list.add(new DynamicPoint(122, bean.faceOval.get(31).x, bean.faceOval.get(31).y, 0.0f));

        //左眉上端
        list.add(new DynamicPoint(127, bean.leftEyeBrowTop.get(0).x, bean.leftEyeBrowTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(129, bean.leftEyeBrowTop.get(1).x, bean.leftEyeBrowTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(133, bean.leftEyeBrowTop.get(2).x, bean.leftEyeBrowTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(90, bean.leftEyeBrowTop.get(3).x, bean.leftEyeBrowTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(125, bean.leftEyeBrowTop.get(4).x, bean.leftEyeBrowTop.get(4).y, 0.0f));

        //左眉下端
        list.add(new DynamicPoint(137, bean.leftEyeBrowBottom.get(0).x, bean.leftEyeBrowBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(77, bean.leftEyeBrowBottom.get(1).x, bean.leftEyeBrowBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(136, bean.leftEyeBrowBottom.get(2).x, bean.leftEyeBrowBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(88, bean.leftEyeBrowBottom.get(3).x, bean.leftEyeBrowBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(128, bean.leftEyeBrowBottom.get(4).x, bean.leftEyeBrowBottom.get(4).y, 0.0f));

        //左眼
        list.add(new DynamicPoint(134, bean.leftEye.get(0).x, bean.leftEye.get(0).y, 0.0f));
        list.add(new DynamicPoint(135, bean.leftEye.get(1).x, bean.leftEye.get(1).y, 0.0f));
        list.add(new DynamicPoint(81, bean.leftEye.get(2).x, bean.leftEye.get(2).y, 0.0f));
        list.add(new DynamicPoint(86, bean.leftEye.get(3).x, bean.leftEye.get(3).y, 0.0f));
        list.add(new DynamicPoint(110, bean.leftEye.get(4).x, bean.leftEye.get(4).y, 0.0f));
        list.add(new DynamicPoint(85, bean.leftEye.get(5).x, bean.leftEye.get(5).y, 0.0f));
        list.add(new DynamicPoint(116, bean.leftEye.get(6).x, bean.leftEye.get(6).y, 0.0f));
        list.add(new DynamicPoint(93, bean.leftEye.get(7).x, bean.leftEye.get(7).y, 0.0f));
        list.add(new DynamicPoint(80, bean.leftEye.get(8).x, bean.leftEye.get(8).y, 0.0f));
        list.add(new DynamicPoint(117, bean.leftEye.get(9).x, bean.leftEye.get(9).y, 0.0f));
        list.add(new DynamicPoint(82, bean.leftEye.get(10).x, bean.leftEye.get(10).y, 0.0f));
        list.add(new DynamicPoint(95, bean.leftEye.get(11).x, bean.leftEye.get(11).y, 0.0f));
        list.add(new DynamicPoint(112, bean.leftEye.get(12).x, bean.leftEye.get(12).y, 0.0f));
        list.add(new DynamicPoint(84, bean.leftEye.get(13).x, bean.leftEye.get(13).y, 0.0f));
        list.add(new DynamicPoint(130, bean.leftEye.get(14).x, bean.leftEye.get(14).y, 0.0f));
        list.add(new DynamicPoint(111, bean.leftEye.get(15).x, bean.leftEye.get(15).y, 0.0f));

        //右眉上端
        list.add(new DynamicPoint(61, bean.rightEyeBrowTop.get(0).x, bean.rightEyeBrowTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(63, bean.rightEyeBrowTop.get(1).x, bean.rightEyeBrowTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(67, bean.rightEyeBrowTop.get(2).x, bean.rightEyeBrowTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(15, bean.rightEyeBrowTop.get(3).x, bean.rightEyeBrowTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(74, bean.rightEyeBrowTop.get(4).x, bean.rightEyeBrowTop.get(4).y, 0.0f));

        //右眉下端
        list.add(new DynamicPoint(72, bean.rightEyeBrowBottom.get(0).x, bean.rightEyeBrowBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(2, bean.rightEyeBrowBottom.get(1).x, bean.rightEyeBrowBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(71, bean.rightEyeBrowBottom.get(2).x, bean.rightEyeBrowBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(13, bean.rightEyeBrowBottom.get(3).x, bean.rightEyeBrowBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(62, bean.rightEyeBrowBottom.get(4).x, bean.rightEyeBrowBottom.get(4).y, 0.0f));

        //右眼
        list.add(new DynamicPoint(5, bean.rightEye.get(0).x, bean.rightEye.get(0).y, 0.0f));
        list.add(new DynamicPoint(20, bean.rightEye.get(1).x, bean.rightEye.get(1).y, 0.0f));
        list.add(new DynamicPoint(47, bean.rightEye.get(2).x, bean.rightEye.get(2).y, 0.0f));
        list.add(new DynamicPoint(10, bean.rightEye.get(3).x, bean.rightEye.get(3).y, 0.0f));
        list.add(new DynamicPoint(40, bean.rightEye.get(4).x, bean.rightEye.get(4).y, 0.0f));
        list.add(new DynamicPoint(11, bean.rightEye.get(5).x, bean.rightEye.get(5).y, 0.0f));
        list.add(new DynamicPoint(6, bean.rightEye.get(6).x, bean.rightEye.get(6).y, 0.0f));
        list.add(new DynamicPoint(69, bean.rightEye.get(7).x, bean.rightEye.get(7).y, 0.0f));
        list.add(new DynamicPoint(68, bean.rightEye.get(8).x, bean.rightEye.get(8).y, 0.0f));
        list.add(new DynamicPoint(42, bean.rightEye.get(9).x, bean.rightEye.get(9).y, 0.0f));
        list.add(new DynamicPoint(64, bean.rightEye.get(10).x, bean.rightEye.get(10).y, 0.0f));
        list.add(new DynamicPoint(9, bean.rightEye.get(11).x, bean.rightEye.get(11).y, 0.0f));
        list.add(new DynamicPoint(43, bean.rightEye.get(12).x, bean.rightEye.get(12).y, 0.0f));
        list.add(new DynamicPoint(23, bean.rightEye.get(13).x, bean.rightEye.get(13).y, 0.0f));
        list.add(new DynamicPoint(7, bean.rightEye.get(14).x, bean.rightEye.get(14).y, 0.0f));
        list.add(new DynamicPoint(48, bean.rightEye.get(15).x, bean.rightEye.get(15).y, 0.0f));

        //鼻梁
        list.add(new DynamicPoint(39, bean.noseBridge.get(0).x, bean.noseBridge.get(0).y, 0.0f));
        list.add(new DynamicPoint(41, bean.noseBridge.get(1).x, bean.noseBridge.get(1).y, 0.0f));

        //鼻子底部
        list.add(new DynamicPoint(96, bean.noseBottom.get(0).x, bean.noseBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(25, bean.noseBottom.get(1).x, bean.noseBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(24, bean.noseBottom.get(2).x, bean.noseBottom.get(2).y, 0.0f));

        //上嘴唇上端
        list.add(new DynamicPoint(115, bean.upperLipTop.get(0).x, bean.upperLipTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(131, bean.upperLipTop.get(1).x, bean.upperLipTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(98, bean.upperLipTop.get(2).x, bean.upperLipTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(105, bean.upperLipTop.get(3).x, bean.upperLipTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(108, bean.upperLipTop.get(4).x, bean.upperLipTop.get(4).y, 0.0f));
        list.add(new DynamicPoint(22, bean.upperLipTop.get(5).x, bean.upperLipTop.get(5).y, 0.0f));
        list.add(new DynamicPoint(37, bean.upperLipTop.get(6).x, bean.upperLipTop.get(6).y, 0.0f));
        list.add(new DynamicPoint(34, bean.upperLipTop.get(7).x, bean.upperLipTop.get(7).y, 0.0f));
        list.add(new DynamicPoint(27, bean.upperLipTop.get(8).x, bean.upperLipTop.get(8).y, 0.0f));
        list.add(new DynamicPoint(65, bean.upperLipTop.get(9).x, bean.upperLipTop.get(9).y, 0.0f));
        list.add(new DynamicPoint(46, bean.upperLipTop.get(10).x, bean.upperLipTop.get(10).y, 0.0f));

        //上嘴唇下端
        list.add(new DynamicPoint(126, bean.upperLipBottom.get(0).x, bean.upperLipBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(92, bean.upperLipBottom.get(1).x, bean.upperLipBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(109, bean.upperLipBottom.get(2).x, bean.upperLipBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(100, bean.upperLipBottom.get(3).x, bean.upperLipBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(114, bean.upperLipBottom.get(4).x, bean.upperLipBottom.get(4).y, 0.0f));
        list.add(new DynamicPoint(29, bean.upperLipBottom.get(5).x, bean.upperLipBottom.get(5).y, 0.0f));
        list.add(new DynamicPoint(38, bean.upperLipBottom.get(6).x, bean.upperLipBottom.get(6).y, 0.0f));
        list.add(new DynamicPoint(18, bean.upperLipBottom.get(7).x, bean.upperLipBottom.get(7).y, 0.0f));
        list.add(new DynamicPoint(60, bean.upperLipBottom.get(8).x, bean.upperLipBottom.get(8).y, 0.0f));

        //下嘴唇上端
        list.add(new DynamicPoint(55, bean.lowLipTop.get(0).x, bean.lowLipTop.get(0).y, 0.0f));
        list.add(new DynamicPoint(32, bean.lowLipTop.get(1).x, bean.lowLipTop.get(1).y, 0.0f));
        list.add(new DynamicPoint(30, bean.lowLipTop.get(2).x, bean.lowLipTop.get(2).y, 0.0f));
        list.add(new DynamicPoint(57, bean.lowLipTop.get(3).x, bean.lowLipTop.get(3).y, 0.0f));
        list.add(new DynamicPoint(59, bean.lowLipTop.get(4).x, bean.lowLipTop.get(4).y, 0.0f));
        list.add(new DynamicPoint(124, bean.lowLipTop.get(5).x, bean.lowLipTop.get(5).y, 0.0f));
        list.add(new DynamicPoint(101, bean.lowLipTop.get(6).x, bean.lowLipTop.get(6).y, 0.0f));
        list.add(new DynamicPoint(103, bean.lowLipTop.get(7).x, bean.lowLipTop.get(7).y, 0.0f));
        list.add(new DynamicPoint(123, bean.lowLipTop.get(8).x, bean.lowLipTop.get(8).y, 0.0f));

        /**
         * 下嘴唇下端
         * lowLipBottom的0、8号点在模型中为废点
         */
        list.add(new DynamicPoint(138, bean.lowLipBottom.get(0).x, bean.lowLipBottom.get(0).y, 0.0f));
        list.add(new DynamicPoint(66, bean.lowLipBottom.get(1).x, bean.lowLipBottom.get(1).y, 0.0f));
        list.add(new DynamicPoint(12, bean.lowLipBottom.get(2).x, bean.lowLipBottom.get(2).y, 0.0f));
        list.add(new DynamicPoint(44, bean.lowLipBottom.get(3).x, bean.lowLipBottom.get(3).y, 0.0f));
        list.add(new DynamicPoint(19, bean.lowLipBottom.get(4).x, bean.lowLipBottom.get(4).y, 0.0f));
        list.add(new DynamicPoint(113, bean.lowLipBottom.get(5).x, bean.lowLipBottom.get(5).y, 0.0f));
        list.add(new DynamicPoint(87, bean.lowLipBottom.get(6).x, bean.lowLipBottom.get(6).y, 0.0f));
        list.add(new DynamicPoint(132, bean.lowLipBottom.get(7).x, bean.lowLipBottom.get(7).y, 0.0f));
        list.add(new DynamicPoint(139, bean.lowLipBottom.get(8).x, bean.lowLipBottom.get(8).y, 0.0f));

        //发际线3个顶点
        float dist2Top = ((bean.leftEyeBrowTop.get(3).y + bean.rightEyeBrowTop.get(3).y) / 2 -
                (bean.faceOval.get(0).y + bean.faceOval.get(35).y) / 2) * 0.6f;
        //poxX: 脸轮廓的起、止点的中点，模拟发际线的x位置；
        float posX = (bean.faceOval.get(0).x + bean.faceOval.get(35).x) / 2;
        float posY = (bean.faceOval.get(0).y + bean.faceOval.get(35).y) / 2 - dist2Top;
        //发际线中部点，index: 70
        list.add(new DynamicPoint(70, posX, posY, 0.0f));

        //发际线左右端点，index: 118(left)、50(right)
        posX = (bean.faceOval.get(33).x + bean.faceOval.get(34).x) / 2;
        posY = (bean.faceOval.get(33).y + bean.faceOval.get(34).y) / 2 - dist2Top;
        list.add(new DynamicPoint(118, posX, posY, 0.0f));

        posX = (bean.faceOval.get(2).x + bean.faceOval.get(3).x) / 2;
        posY = (bean.faceOval.get(2).y + bean.faceOval.get(3).y) / 2 - dist2Top;
        list.add(new DynamicPoint(50, posX, posY, 0.0f));

        //脖子顶点，共6个
        float neckHeight = (bean.faceOval.get(18).y - bean.lowLipBottom.get(4).y) * 0.8f;
        posX = (bean.faceOval.get(22).x + bean.faceOval.get(23).x) / 2;
        posY = (bean.faceOval.get(22).y + bean.faceOval.get(23).y) / 2 + neckHeight * 0.3f;
        list.add(new DynamicPoint(94, posX, posY, 0.0f));//脖子左边点1

        posY = (bean.faceOval.get(22).y + bean.faceOval.get(23).y) / 2 + neckHeight * 1f;
        list.add(new DynamicPoint(104, posX, posY, 0.0f));//脖子左边点2

        posX = bean.faceOval.get(18).x;
        posY = bean.faceOval.get(18).y + neckHeight * 0.2f;
        list.add(new DynamicPoint(16, posX, posY, 0.0f));//脖子中部点1

        posY = bean.faceOval.get(18).y + neckHeight * 1f;
        list.add(new DynamicPoint(58, posX, posY, 0.0f));//脖子中部点2

        posX = (bean.faceOval.get(13).x + bean.faceOval.get(14).x) / 2;
        posY = (bean.faceOval.get(13).y + bean.faceOval.get(14).y) / 2 + neckHeight * 0.2f;
        list.add(new DynamicPoint(21, posX, posY, 0.0f));//脖子右边点1

        posY = (bean.faceOval.get(13).y + bean.faceOval.get(14).y) / 2 + neckHeight * 1f;
        list.add(new DynamicPoint(33, posX, posY, 0.0f));//脖子右边点2

        return list;
    }

    public interface OnBuildOldifyImgListener {
        /**
         * 返回老化效果图
         * @param bitmap 老化效果图，为空时表示生成效果图失败
         */
        void onBuildOldifyImg(Bitmap bitmap, int oldifyType);
    }

}
